﻿//
// Copyright © MixModes Inc. 2011
//

using System;
using System.ComponentModel;
using System.Linq.Expressions;
using System.Runtime.Serialization;
using MixModes.Phone.Synergy.Framework;

namespace MixModes.Phone.Synergy.ViewModels
{
    /// <summary>
    /// Base ViewModel class
    /// </summary>
    [DataContract] 
    public abstract class ViewModelBase : INotifyPropertyChanged, IDisposable
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="T:System.Windows.DependencyObject"/> class.
        /// </summary>
        /// <remarks></remarks>
        protected ViewModelBase()
        {
            PhoneApplication.Instance.LoadSettings += OnLoadState;
            PhoneApplication.Instance.SaveSettings += OnSaveState;
        }        

        /// <summary>
        /// Occurs when a property value changes.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;
        
        /// <summary>
        /// Raises the property changed event
        /// </summary>
        /// <param name="x">Expression of the form: x=> this.PropertyName</param>
        protected void RaisePropertyChanged<R>(Expression<Func<object, R>> x)
        {
            var body = x.Body as MemberExpression;
            if (body == null)
            {
                throw new ArgumentException("Argument should be of the form: x=>this.Property");
            }

            string propertyName = body.Member.Name;

            PropertyChangedEventHandler handler = this.PropertyChanged;

            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        /// <summary>
        /// Saves the state.
        /// </summary>
        /// <param name="storageArgs">The <see cref="MixModes.Phone.Synergy.Framework.DataStoreEventArgs"/> instance containing the event data.</param>
        protected virtual void SaveState(DataStoreEventArgs storageArgs)
        {
        }

        /// <summary>
        /// Loads the state.
        /// </summary>
        /// <param name="storageArgs">The <see cref="MixModes.Phone.Synergy.Framework.DataStoreEventArgs"/> instance containing the event data.</param>
        protected virtual void LoadState(DataStoreEventArgs storageArgs)
        {
        }

        /// <summary>
        /// Called when state is to be persisted
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="MixModes.Phone.Synergy.Framework.DataStoreEventArgs"/> instance containing the event data.</param>
        private void OnSaveState(object sender, DataStoreEventArgs e)
        {
            SaveState(e);
        }

        /// <summary>
        /// Called when state is to be loaded
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="MixModes.Phone.Synergy.Framework.DataStoreEventArgs"/> instance containing the event data.</param>
        private void OnLoadState(object sender, DataStoreEventArgs e)
        {
            LoadState(e);
        }

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            PhoneApplication.Instance.LoadSettings -= OnLoadState;
            PhoneApplication.Instance.SaveSettings -= OnSaveState;            
        }
    }
}
